package cn.falconnect.adserver.adapter.persistence;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Repository;

import cn.falconnect.adserver.domain.ad.AdSpace;
import cn.falconnect.adserver.domain.ad.GuidValueObject;

@Repository
public class GuidRepositoryImpl implements GuidRepository {

	@Resource(name = "guidRedisTemplateV2")
	private ValueOperations<String, GuidValueObject> guidValueOperationsV2;
	
	@Resource(name = "cacheRedisTemplate")
	private ValueOperations<String, Long> counterOperations;
	
	@Resource(name = "cacheRedisTemplate")
	private RedisTemplate<String, AdSpace> redisTemplate;

	// @Resource(name = "guidRedisTemplate")
	// private ValueOperations<String, GuidValueObject> guidValueOperations;

	@Autowired
	private ConfigRepository configRepository;
	
	
	
	/**
	 * GUID对象前缀
	 */
	private static final String CACHE_KEY_PREFIX_GUID = "guid:";
	
	/**
	 * 根据传入的GUID参数构建GUID对象缓存使用的KEY
	 * @param guid 原始的GUID唯一标识
	 * @return
	 */
	private String buildCachekey(String guid){
		StringBuffer sb = new StringBuffer(CACHE_KEY_PREFIX_GUID);
		sb.append(GuidValueObject.CURRENT_VERSION).append(":").append(guid);
		return sb.toString();
	}
	
	/**
	 * 根据传入参数构建GUID点击累计次数缓存KEY
	 * @param guid GUID对象唯一标识
	 * @return
	 */
	private String buildCountClickCacheKey(String guid) {
		return new StringBuilder(guid).append(":").append("click").append(":").append("count").toString();
	}
	
	/**
	 * 
	 * @return
	 */
	private String buildCountClickTimeCacheKey(String guid) {
		return new StringBuilder(guid).append(":").append("click").append(":").append("count").append(":")
				.append("time").toString();
	}
	
	/**
	 * 
	 * @return
	 */
	private String buildCountImpressionsTimeKey(String guid) {
		return new StringBuilder(guid).append(":").append("impressions").append(":").append("count").append(":")
				.append("time").toString();
	}
	
	/**
	 * 根据传入参数构建GUID 曝光次数计数缓存KEY
	 * @param guid
	 * @return
	 */
	private String buildCountImpressionsCacheKey(String guid) {
		return new StringBuilder(guid).append(":").append("impressions").append(":").append("count").toString();
	}
	
	/**
	 * 生成GUID
	 * @return
	 */
	private String createNewGUID(){
		String uuid = UUID.randomUUID().toString().replaceAll("-", "").toLowerCase();
		return uuid;
	}

	@Override
	public String storeGuid(GuidValueObject guidVo, int channelId) {
		guidVo.setGuid(createNewGUID());
//		String guidCacheKey = guidVo.toGUIDKey();
		String guidCacheKey = buildCachekey(guidVo.getGuid());
		guidValueOperationsV2.set(guidCacheKey, guidVo, configRepository.fetchGuidTimeout(channelId), TimeUnit.MINUTES);
		return guidVo.getGuid();
	}

	@Override
	public GuidValueObject findGuidVo(String guidKey) {
		if (StringUtils.isBlank(guidKey))
			return null;
		// if (guidKey.length() == 32) {
		// return guidValueOperations.get(guidKey);
		// } else {
		// return guidValueOperationsV2.get(guidKey);
		// }
		
		//如果传入的GUID是没有带缓存前缀标识的
		GuidValueObject guidValueObject = guidValueOperationsV2.get(buildCachekey(guidKey));
		if (guidValueObject != null)
			return guidValueObject;

		return guidValueOperationsV2.get(guidKey);

	}
	
	@Override
	public long countGuidClick(GuidValueObject guidVO, int channelId) {
		String guidCountOfClickCacheKey = buildCountClickCacheKey(guidVO.getGuid());
		String guidCountOfClickTimerCacheKey = buildCountClickTimeCacheKey(guidVO.getGuid());
		long i = counterOperations.increment(guidCountOfClickCacheKey, 1);
		counterOperations.set(guidCountOfClickTimerCacheKey, System.currentTimeMillis());
		// if (i == 1) {
		redisTemplate.expire(guidCountOfClickCacheKey, configRepository.fetchGuidTimeout(channelId), TimeUnit.MINUTES);
		redisTemplate.expire(guidCountOfClickTimerCacheKey, configRepository.fetchGuidTimeout(channelId),
				TimeUnit.MINUTES);
		// }
		return i;
	}
	
	@Override
	public long countGuidImpressions(GuidValueObject guidVO, int channelId) {
		String guidImpressionCountCacheKey = buildCountImpressionsCacheKey(guidVO.getGuid());
		String guidImpressionTimerCacheKey = buildCountImpressionsTimeKey(guidVO.getGuid());
		long i = counterOperations.increment(guidImpressionCountCacheKey, 1);
		counterOperations.set(guidImpressionTimerCacheKey, System.currentTimeMillis());
		// if (i == 1) {
		redisTemplate.expire(guidImpressionCountCacheKey, configRepository.fetchGuidTimeout(channelId),
				TimeUnit.MINUTES);
		redisTemplate.expire(guidImpressionTimerCacheKey, configRepository.fetchGuidTimeout(channelId),
				TimeUnit.MINUTES);
		// }
		return i;
	}

}
